"""
溢价历史数据模块
获取最近6个月的溢价历史数据
"""
import time
from typing import Dict, List, Optional
from datetime import datetime, timedelta
from loguru import logger

try:
    import okx.PublicData as PublicData
except ImportError:
    logger.warning("okx SDK未安装，请运行: pip install okx")
    PublicData = None


class PremiumHistoryManager:
    """溢价历史数据管理器"""
    
    # 限速配置：20次/2s
    RATE_LIMIT_REQUESTS = 20
    RATE_LIMIT_WINDOW = 2.0  # 秒
    
    def __init__(self, sandbox: bool = True):
        """
        初始化溢价历史数据管理器
        
        Args:
            sandbox: 是否使用模拟盘，True=模拟盘(1)，False=实盘(0)
        """
        if PublicData is None:
            raise ImportError("okx SDK未安装，请运行: pip install okx")
        
        self.sandbox = sandbox
        flag = "1" if sandbox else "0"
        
        # 初始化OKX公共数据API
        self.public_api = PublicData.PublicAPI(flag=flag)
        
        # 限速控制
        self.request_times: List[float] = []  # 请求时间戳列表
        
        # 数据缓存
        self.premium_history_cache: Dict[str, List[Dict]] = {}  # inst_id -> premium_data
        self.cache_expire_time: Dict[str, datetime] = {}  # inst_id -> expire_time
        self.cache_duration = timedelta(minutes=5)  # 缓存5分钟
        
        logger.info(f"溢价历史数据管理器已初始化 (模式: {'模拟盘' if sandbox else '实盘'})")
    
    def _check_rate_limit(self):
        """
        检查并执行限速
        限速规则：20次/2s (IP)
        """
        now = time.time()
        
        # 移除2秒前的请求记录
        self.request_times = [t for t in self.request_times 
                             if now - t < self.RATE_LIMIT_WINDOW]
        
        # 如果达到限速上限，等待
        if len(self.request_times) >= self.RATE_LIMIT_REQUESTS:
            oldest_request = self.request_times[0]
            wait_time = self.RATE_LIMIT_WINDOW - (now - oldest_request)
            
            if wait_time > 0:
                logger.debug(f"触发限速，等待 {wait_time:.2f} 秒")
                time.sleep(wait_time)
                # 重新计算
                now = time.time()
                self.request_times = [t for t in self.request_times 
                                     if now - t < self.RATE_LIMIT_WINDOW]
        
        # 记录本次请求
        self.request_times.append(now)
    
    def get_premium_history(self, inst_id: str, 
                           before: Optional[str] = None,
                           after: Optional[str] = None,
                           limit: int = 100,
                           use_cache: bool = True) -> List[Dict]:
        """
        获取溢价历史数据（最近6个月）
        
        Args:
            inst_id: 产品ID，如 BTC-USDT-SWAP
            before: 请求此时间戳之前的分页内容（毫秒时间戳）
            after: 请求此时间戳之后的分页内容（毫秒时间戳）
            limit: 返回结果数量，最大100，默认100
            use_cache: 是否使用缓存
            
        Returns:
            溢价历史数据列表，每条记录包含以下字段：
            - instId: 产品ID
            - premium: 溢价率
            - ts: 数据返回时间（毫秒时间戳）
        """
        # 生成缓存键
        cache_key = f"{inst_id}_{before}_{after}_{limit}"
        
        # 检查缓存
        if use_cache and cache_key in self.premium_history_cache:
            expire_time = self.cache_expire_time.get(cache_key)
            if expire_time and datetime.now() < expire_time:
                logger.debug(f"从缓存获取溢价历史数据: {cache_key}")
                return self.premium_history_cache[cache_key]
        
        # 执行限速检查
        self._check_rate_limit()
        
        try:
            # 构建请求参数
            params = {
                "instId": inst_id,
                "limit": str(limit)
            }
            if before:
                params["before"] = before
            if after:
                params["after"] = after
            
            logger.info(f"获取溢价历史数据: {params}")
            result = self.public_api.get_premium_history(**params)
            
            # 检查响应
            if result.get("code") != "0":
                error_msg = result.get("msg", "未知错误")
                logger.error(f"获取溢价历史数据失败: {error_msg}")
                raise RuntimeError(f"API错误: {error_msg}")
            
            # 提取数据
            data_list = result.get("data", [])
            logger.info(f"获取溢价历史数据成功: {len(data_list)} 条记录")
            
            # 更新缓存
            if use_cache:
                self.premium_history_cache[cache_key] = data_list
                self.cache_expire_time[cache_key] = datetime.now() + self.cache_duration
            
            return data_list
            
        except Exception as e:
            logger.error(f"获取溢价历史数据异常: {e}")
            raise
    
    def get_latest_premium(self, inst_id: str) -> Optional[Dict]:
        """
        获取最新的溢价数据
        
        Args:
            inst_id: 产品ID
            
        Returns:
            最新的溢价数据，如果不存在返回None
        """
        data_list = self.get_premium_history(inst_id, limit=1)
        
        if data_list:
            return data_list[0]
        return None
    
    def get_premium_details(self, inst_id: str, limit: int = 100) -> Dict:
        """
        获取溢价详细信息（包含格式化数据和统计）
        
        Args:
            inst_id: 产品ID
            limit: 数据条数
            
        Returns:
            详细信息字典
        """
        data_list = self.get_premium_history(inst_id, limit=limit)
        
        if not data_list:
            raise ValueError(f"无法获取溢价历史数据: {inst_id}")
        
        # 格式化数据
        formatted_data = []
        premiums = []
        
        for item in data_list:
            premium = float(item.get("premium", 0))
            ts = int(item.get("ts", 0))
            timestamp_str = datetime.fromtimestamp(ts / 1000).strftime("%Y-%m-%d %H:%M:%S")
            
            formatted_data.append({
                "premium": premium,
                "premium_pct": premium * 100,
                "timestamp": timestamp_str,
                "timestamp_ms": ts,
            })
            
            premiums.append(premium)
        
        # 计算统计信息
        avg_premium = sum(premiums) / len(premiums) if premiums else 0
        max_premium = max(premiums) if premiums else 0
        min_premium = min(premiums) if premiums else 0
        
        return {
            "inst_id": inst_id,
            "data": formatted_data,
            "statistics": {
                "count": len(premiums),
                "avg_premium": avg_premium,
                "avg_premium_pct": avg_premium * 100,
                "max_premium": max_premium,
                "max_premium_pct": max_premium * 100,
                "min_premium": min_premium,
                "min_premium_pct": min_premium * 100,
            }
        }
    
    def get_premium_trend(self, inst_id: str, days: int = 7) -> Dict:
        """
        获取溢价趋势（指定天数）
        
        Args:
            inst_id: 产品ID
            days: 查询天数，默认7天
            
        Returns:
            溢价趋势信息
        """
        # 计算时间戳
        now = datetime.now()
        after_time = now - timedelta(days=days)
        after_ts = str(int(after_time.timestamp() * 1000))
        
        data_list = self.get_premium_history(inst_id, after=after_ts, limit=100)
        
        if not data_list:
            return {
                "inst_id": inst_id,
                "days": days,
                "data_points": 0,
                "trend": "无数据"
            }
        
        # 分析趋势
        premiums = [float(item.get("premium", 0)) for item in data_list]
        
        if len(premiums) >= 2:
            first_premium = premiums[-1]  # 最早的数据
            last_premium = premiums[0]    # 最新的数据
            change = last_premium - first_premium
            change_pct = (change / abs(first_premium) * 100) if first_premium != 0 else 0
            
            if change > 0:
                trend = "上升"
            elif change < 0:
                trend = "下降"
            else:
                trend = "持平"
        else:
            change = 0
            change_pct = 0
            trend = "数据不足"
        
        return {
            "inst_id": inst_id,
            "days": days,
            "data_points": len(premiums),
            "first_premium": premiums[-1] if premiums else 0,
            "last_premium": premiums[0] if premiums else 0,
            "change": change,
            "change_pct": change_pct,
            "trend": trend,
        }
    
    def compare_premiums(self, inst_ids: List[str]) -> List[Dict]:
        """
        比较多个产品的溢价
        
        Args:
            inst_ids: 产品ID列表
            
        Returns:
            比较结果列表
        """
        results = []
        
        for inst_id in inst_ids:
            try:
                latest = self.get_latest_premium(inst_id)
                if latest:
                    results.append({
                        "inst_id": inst_id,
                        "premium": float(latest.get("premium", 0)),
                        "premium_pct": float(latest.get("premium", 0)) * 100,
                        "timestamp": datetime.fromtimestamp(
                            int(latest.get("ts", 0)) / 1000
                        ).strftime("%Y-%m-%d %H:%M:%S"),
                    })
            except Exception as e:
                logger.error(f"获取 {inst_id} 溢价失败: {e}")
        
        # 按溢价排序
        results.sort(key=lambda x: x["premium"], reverse=True)
        
        return results
    
    def clear_cache(self, cache_key: Optional[str] = None):
        """
        清除缓存
        
        Args:
            cache_key: 缓存键，如果为None则清除所有缓存
        """
        if cache_key:
            if cache_key in self.premium_history_cache:
                del self.premium_history_cache[cache_key]
            if cache_key in self.cache_expire_time:
                del self.cache_expire_time[cache_key]
            logger.info(f"已清除 {cache_key} 的缓存")
        else:
            self.premium_history_cache.clear()
            self.cache_expire_time.clear()
            logger.info("已清除所有溢价历史数据缓存")
    
    def get_cache_stats(self) -> Dict:
        """
        获取缓存统计信息
        
        Returns:
            缓存统计字典
        """
        total_cached = len(self.premium_history_cache)
        valid_cached = sum(1 for key in self.premium_history_cache.keys()
                          if key in self.cache_expire_time and
                          datetime.now() < self.cache_expire_time[key])
        
        return {
            "total_cached": total_cached,
            "valid_cached": valid_cached,
            "expired_cached": total_cached - valid_cached,
            "cache_duration_minutes": self.cache_duration.total_seconds() / 60,
        }


# 便捷函数
def get_premium_history(inst_id: str, sandbox: bool = True, **kwargs) -> List[Dict]:
    """
    便捷函数：获取溢价历史数据
    
    Args:
        inst_id: 产品ID
        sandbox: 是否使用模拟盘
        **kwargs: 其他参数传递给get_premium_history
        
    Returns:
        溢价历史数据列表
    """
    manager = PremiumHistoryManager(sandbox=sandbox)
    return manager.get_premium_history(inst_id, **kwargs)


def get_latest_premium(inst_id: str, sandbox: bool = True) -> Optional[Dict]:
    """
    便捷函数：获取最新的溢价数据
    
    Args:
        inst_id: 产品ID
        sandbox: 是否使用模拟盘
        
    Returns:
        最新的溢价数据
    """
    manager = PremiumHistoryManager(sandbox=sandbox)
    return manager.get_latest_premium(inst_id)


def get_premium_trend(inst_id: str, days: int = 7, sandbox: bool = True) -> Dict:
    """
    便捷函数：获取溢价趋势
    
    Args:
        inst_id: 产品ID
        days: 查询天数
        sandbox: 是否使用模拟盘
        
    Returns:
        溢价趋势信息
    """
    manager = PremiumHistoryManager(sandbox=sandbox)
    return manager.get_premium_trend(inst_id, days)


def compare_premiums(inst_ids: List[str], sandbox: bool = True) -> List[Dict]:
    """
    便捷函数：比较多个产品的溢价
    
    Args:
        inst_ids: 产品ID列表
        sandbox: 是否使用模拟盘
        
    Returns:
        比较结果列表
    """
    manager = PremiumHistoryManager(sandbox=sandbox)
    return manager.compare_premiums(inst_ids)
